<?php


namespace app\zyhsapi\controller\v1;


use app\common\lib\exception\ApiException;
use app\common\lib\Util;
use app\zyhsapi\controller\ZyhsAuth;
use app\zyhsapi\model\ZyhsAppleidUser;
use app\zyhsapi\model\ZyhsLoginLog;
use app\zyhsapi\model\ZyhsQq;
use app\zyhsapi\model\ZyhsUser;
use app\zyhsapi\model\ZyhsUserPush;
use app\zyhsapi\model\ZyhsUserZx;
use app\zyhsapi\model\ZyhsWechat;
use app\zyhsapi\model\ZyhsWeibo;
use app\zyhsapi\service\CacheZyhs;
use GuzzleHttp\Exception\GuzzleException;
use think\Db;
use think\Exception;
use think\Log;
use think\response\Json;

/**
 * @version 2.4.0
 * Class LogoutAccount
 * @package app\api\controller\v20
 */
class LogoutAccount extends ZyhsAuth
{
    /**
     * 注销页
     * @return Json
     * @throws \Exception
     */
    public function index()
    {
        //注销类型，1=>微信，2=>qq,3=>微博 4=>手机号
        $data['type'] = (new ZyhsLoginLog())->where('uid', $this->user['id'])->order('id desc')->value('login_type');
        if ($this->user['tel'])
        {
            $str = substring($this->user['tel'], '-');
            $tel = $str['after'];
            $data['area_code'] = (int)$str['before'] ?: 86;
            $data['tel'] = Util::hidtel($tel, $data['area_code']);
        }
        return show(config('code.success'), '获取成功', $data);
    }

    /**
     * 获取用户三方信息
     * @return Json
     * @throws GuzzleException
     * @throws ApiException
     * @throws \Exception
     */
    public function getUserInfo()
    {
        $param = input('param.param');
        $param = $param ? json_decode($param, true) : [];
        $type = input('param.type/d');
        $data = [
            'nickname' => '',
            'avatar' => '',
            'unionid' => '',
            'openid' => '',
            'wbuid' => '',
        ];
        switch ($type)
        {
            case 1:
                $zyhsWechatModel = new ZyhsWechat();
                $user_info = $zyhsWechatModel->WechatInfo($param);
                if (!$user_info)
                {
                    return show(config('code.error'), '您未注册此类型账号');
                }
                $data['unionid'] = $user_info['unionid'];
                break;
            case 2:
                //获qq方用户信息
                $QqModel = new ZyhsQq();
                $user_info = $QqModel->QqInfo($param);
                if (!$user_info)
                {
                    return show(config('code.error'), '您未注册此类型账号');
                }
                $data['openid'] = $user_info['unionid'];
                break;
            case 3:
                $user_info = (new ZyhsWeibo())->WeiboInfo($param);
                if (!$user_info)
                {
                    return show(config('code.error'), '您未注册此类型账号');
                }
                $data['wbuid'] = $user_info['unionid'];
                break;
            default:
                return show(config('code.error'), '您未注册此类型账号');
                break;
        }
        $data['nickname'] = $user_info['nickname'];
        $data['avatar'] = $user_info['headimgurl'];
        return show(config('code.success'), '获取成功', $data);
    }

    /**
     * 账户注销，获取app的用户信息
     * 1=>微信，2=>qq,3=>微博 4=>手机号
     * 注销唯一标识，手机号（code）微信(unionid)或QQ(openid)或微博唯一标识(uid)
     * @throws \Exception
     */
    public function out()
    {
        $param = input('param.param/s');
        $type = input('param.type/d');
        if (!$param)
        {
            return show(config('code.error'), '缺少信息');
        }
        switch ($type)
        {
            case 1://验证微信授权
                $wechatInfo = (new ZyhsWechat())->getWechatInfo($param);
                if ($wechatInfo && $this->user['id'] == $wechatInfo['uid'])
                {
                    $res = true;
                } else
                {   // todo 失败次数限制
                    return show(config('code.error'), '微信认证失败');
                }
                break;
            case 2://验证qq授权
                $QqInfo = (new ZyhsQq())->getUserQqInfoFromCache($param);
                if ($QqInfo && $this->user['id'] == $QqInfo['uid'])
                {
                    $res = true;
                } else
                {   // todo 失败次数限制
                    return show(config('code.error'), 'qq认证失败');
                }
                break;
            case 3://验证微博授权
                $WbInfo = (new ZyhsWeibo())->getUserWbInfoFromCache($param);
                if ($WbInfo && $this->user['id'] == $WbInfo['uid'])
                {
                    $res = true;
                } else
                {   // todo 失败次数限制
                    return show(config('code.error'), '微博认证失败');
                }
                break;
            case 4://验证手机号
                $appConfig = config('app');
                if (!in_array($this->user['tel'], $appConfig['mobile'])
                    || $param != substr($appConfig['code'] * (substr($this->user['tel'], 3, 6)), 0, 6)
                )
                {
                    if ($param >= 100000 && $param == CacheZyhs::get('logout:' . $this->user['tel']))
                    {
                        $res = true;
                    } else
                    {   // todo 失败次数限制
                        return show(config('code.error'), '验证码错误');
                    }
                } else
                {
                    $res = true;
                }
                break;
            case 5://验证苹果登陆
                // 验证是否注册过
                $appleInfo = (new ZyhsAppleidUser())->getUserInfo($param);
                if ($appleInfo && $this->user['id'] == $appleInfo['uid'])
                {
                    $res = true;
                } else
                {   // todo 失败次数限制
                    return show(config('code.error'), '微博认证失败');
                }
                break;
            default:
                $res = false;
                break;
        }
        //去注销
        $result = false;
        if ($res === true)
        {
            $result = $this->userOut($type);
        }

        if ($result === true)
        {
            // 删除 验证码
            CacheZyhs::rm('logout:' . $this->user['tel']);
            return show(config('code.success'), '注销成功');
        }
        return show(config('code.error'), '服务异常；注销失败请稍后再试');
    }

    /**
     * 用户注销
     * @param int $outType 注销验证方式 1=>微信，2=>qq,3=>微博 4=>手机号
     * @return bool
     * @throws \Exception
     */
    protected function userOut($outType)
    {
        Db::startTrans();
        try
        {
            $userZxModel = new ZyhsUserZx();
            $tel = $this->user['tel'] ?: '';
            $telNew = null;
            if ($tel)
            {
                // 获取手机号注销次数
                $num = $userZxModel->getZxNum(4, $tel);
                $telNew = $tel . '_' . ($num + 1) . 'zx';
            }
            $zyhsWechatModel = new ZyhsWechat();
            $wechatInfo = $zyhsWechatModel->getWechatInfo((int)$this->user['id'], 2);
            $unionid = $wechatInfo ? $wechatInfo['unionid'] : '';
            //注销微信
            if ($unionid)
            {
                $num = $userZxModel->getZxNum(1, $unionid);
                $wechatNew = $unionid . '_' . ($num + 1) . 'zx';
                $zyhsWechatModel->UpdateData([
                    'unionid' => $wechatNew
                ], ['uid' => $this->user['id']], $this->user['id'], $unionid);
            }
            $zyhsQqModel = new ZyhsQq();
            $QqInfo = $zyhsQqModel->getUserQqInfoFromCache($this->user['id'], 2);
            $qq_unionid = $QqInfo ? $QqInfo['unionid'] : '';
            //注销qq
            if ($qq_unionid)
            {
                $num = $userZxModel->getZxNum(2, $qq_unionid);
                $qqNew = $qq_unionid . '_' . ($num + 1) . 'zx';
                // 重置注销 微信unionid
                $zyhsQqModel->UpdateData([
                    'unionid' => $qqNew
                ], ['uid' => $this->user['id']], $this->user['id'], $qq_unionid);
            }
            $zyhsWeiboModel = new ZyhsWeibo();
            $WbInfo = $zyhsWeiboModel->getUserWbInfoFromCache($this->user['id'], 2);
            $wuid = $WbInfo ? $WbInfo['wbuid'] : '';
            //注销微博
            if ($wuid)
            {
                $num = $userZxModel->getZxNum(3, $wuid);
                $wbNew = $wuid . '_' . ($num + 1) . 'zx';
                $zyhsWeiboModel->UpdateData([
                    'wbuid' => $wbNew,
                ], ['uid' => $this->user['id']], $this->user['id'], $wuid);
            }
            //苹果注销
            $zyhsAppleidUserModel = new ZyhsAppleidUser();
            $appleId = $zyhsAppleidUserModel->where('uid', $this->user['id'])->value('apple_id');
            if ($appleId)
            {
                $num = $userZxModel->getZxNum(5, $appleId);
                $appleIdNew = $appleId . '_' . ($num + 1) . 'zx';
                $zyhsAppleidUserModel->UpdateData([
                    'apple_id' => $appleIdNew,
                ], ['uid' => $this->user['id']], $appleId);
            }

            // 重置手机号和清空token
            (new ZyhsUser())->updateUserinfo(['id' => (int)$this->user['id']], [
                'tel' => $telNew,
                'token' => '',
                'token_expire' => 0
            ]);
            //硬删用户推送数据
            (new ZyhsUserPush())->Del($this->user['id']);

            $zxData = [
                'uid' => $this->user['id'],
                'type' => $outType,
                'tel' => $tel ?? '',
                'unionid' => $unionid ?? '',
                'qq_unionid' => $qq_unionid ?? '',
                'wuid' => $wuid ?? '',
                'apple_id' => $appleId ?? '',
                'aid' => 0,
                'create_time' => time()
            ];
            // 写入注销记录
            $userZxModel->save($zxData);

            Db::commit();
        }
        catch (Exception $e)
        {
            Db::rollback();
            Log::write('注销失败：' . $e->getMessage() . '注销方式' . $outType . '失败文件信息：' . $e->getFile() . $e->getLine(), 'error', true);
            return false;
        }

        return true;
    }
}
